// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package roadmap_api_serv

import (
	"context"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/lvup-api/dao/user_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_api"
	"gitcode.com/lvupclub/proto-gen-go.git/src/user_api"
	"github.com/google/uuid"
)

type RoadmapApiImpl struct {
	roadmap_api.UnimplementedRoadmapApiServer
}

func (apiImpl *RoadmapApiImpl) Create(ctx context.Context, req *roadmap_api.CreateRequest) (*roadmap_api.CreateResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.CreateResponse{
			Code:   roadmap_api.CreateResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以创建路线图
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_api.CreateResponse{
			Code:   roadmap_api.CreateResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	roadmapId := uuid.NewString()
	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.RoadmapInfoDao.Insert(sessCtx, &roadmap_dao.RoadmapInfoDbItem{
			RoadmapId: roadmapId,
			BasicInfo: roadmap_dao.BasicRoadmapInfoDbItem{
				Name:            req.BasicInfo.Name,
				Desc:            req.BasicInfo.Desc,
				EnableJoinApply: req.BasicInfo.EnableJoinApply,
			},
			OwnerUserId: sessItem.UserId,
			CreateTime:  nowTime,
			UpdateTime:  nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &roadmap_api.CreateResponse{
			Code:      roadmap_api.CreateResponse_CODE_OK,
			RoadmapId: roadmapId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_api.CreateResponse), nil
}

func (apiImpl *RoadmapApiImpl) Update(ctx context.Context, req *roadmap_api.UpdateRequest) (*roadmap_api.UpdateResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.UpdateResponse{
			Code:   roadmap_api.UpdateResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以更新路线图
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_api.UpdateResponse{
			Code:   roadmap_api.UpdateResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_api.UpdateResponse{
			Code:   roadmap_api.UpdateResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线不存在",
		}, nil
	}
	//只有路线图owner可以修改
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_api.UpdateResponse{
			Code:   roadmap_api.UpdateResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		err = roadmap_dao.RoadmapInfoDao.UpdateBasic(sessCtx, req.RoadmapId, &roadmap_dao.BasicRoadmapInfoDbItem{
			Name:            req.BasicInfo.Name,
			Desc:            req.BasicInfo.Desc,
			EnableJoinApply: req.BasicInfo.EnableJoinApply,
		}, nowTime)
		if err != nil {
			return nil, err
		}
		return &roadmap_api.UpdateResponse{
			Code: roadmap_api.UpdateResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_api.UpdateResponse), nil
}

func (apiImpl *RoadmapApiImpl) Remove(ctx context.Context, req *roadmap_api.RemoveRequest) (*roadmap_api.RemoveResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.RemoveResponse{
			Code:   roadmap_api.RemoveResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//只有教练可以删除路线图
	if userItem.BasicInfo.UserRole != user_api.USER_ROLE_USER_ROLE_COACH {
		return &roadmap_api.RemoveResponse{
			Code:   roadmap_api.RemoveResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_api.RemoveResponse{
			Code: roadmap_api.RemoveResponse_CODE_OK,
		}, nil
	}
	//只有路线图owner可以删除
	if roadmapItem.OwnerUserId != sessItem.UserId {
		return &roadmap_api.RemoveResponse{
			Code:   roadmap_api.RemoveResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx context.Context) (interface{}, error) {
		//删除路线图
		err = roadmap_dao.RoadmapInfoDao.Remove(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除路线图成员
		err = roadmap_dao.RoadmapMemberDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除邀请
		err = roadmap_dao.InviteInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除节点和连线
		err = roadmap_dao.NodeInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		err = roadmap_dao.EdgeInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除rag配置
		err = roadmap_dao.RagConfigDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除聊天内容
		err = roadmap_dao.ChatMessageDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除Qa对话
		err = roadmap_dao.ThreadInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		err = roadmap_dao.ThreadContentDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除学习计划
		err = roadmap_dao.PlanInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		err = roadmap_dao.PlanItemInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		//删除加入申请
		err = roadmap_dao.ApplyInfoDao.RemoveByRoadmap(sessCtx, req.RoadmapId)
		if err != nil {
			return nil, err
		}
		return &roadmap_api.RemoveResponse{
			Code: roadmap_api.RemoveResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	return ret.(*roadmap_api.RemoveResponse), nil
}

func (apiImpl *RoadmapApiImpl) ListMy(ctx context.Context, req *roadmap_api.ListMyRequest) (*roadmap_api.ListMyResponse, error) {
	emptyList := []*roadmap_api.RoadmapInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.ListMyResponse{
			Code:        roadmap_api.ListMyResponse_CODE_WRONG_SESSION,
			ErrMsg:      "会话不存在",
			RoadmapList: emptyList,
		}, nil
	}

	memberItemList, err := roadmap_dao.RoadmapMemberDao.ListByMember(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	roadmapIdList := []string{}
	for _, memberItem := range memberItemList {
		roadmapIdList = append(roadmapIdList, memberItem.RoadmapId)
	}
	roadmapItemList, err := roadmap_dao.RoadmapInfoDao.ListById(ctx, roadmapIdList)
	if err != nil {
		return nil, err
	}
	//补全用户信息
	userIdList := []string{}
	for _, roadmapItem := range roadmapItemList {
		userIdList = append(userIdList, roadmapItem.OwnerUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}
	//生成结果
	roadmapList := []*roadmap_api.RoadmapInfo{}
	for _, roadmapItem := range roadmapItemList {
		roadmap := roadmapItem.ToRoadmapInfo()
		userItem, ok := userItemMap[roadmapItem.OwnerUserId]
		if ok {
			roadmap.OwnerDisplayName = userItem.BasicInfo.DisplayName
			roadmap.OwnerLogoUri = userItem.BasicInfo.LogoUri
		}
		roadmapList = append(roadmapList, roadmap)
	}

	return &roadmap_api.ListMyResponse{
		Code:        roadmap_api.ListMyResponse_CODE_OK,
		RoadmapList: roadmapList,
	}, nil
}

func (apiImpl *RoadmapApiImpl) ListMyOwn(ctx context.Context, req *roadmap_api.ListMyOwnRequest) (*roadmap_api.ListMyOwnResponse, error) {
	emptyList := []*roadmap_api.RoadmapInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.ListMyOwnResponse{
			Code:        roadmap_api.ListMyOwnResponse_CODE_WRONG_SESSION,
			ErrMsg:      "会话不存在",
			RoadmapList: emptyList,
		}, nil
	}
	userItem, err := user_dao.UserInfoDao.GetById(ctx, sessItem.UserId)
	if err != nil {
		return &roadmap_api.ListMyOwnResponse{
			Code:        roadmap_api.ListMyOwnResponse_CODE_NO_PERMISSION,
			ErrMsg:      "没有权限",
			RoadmapList: emptyList,
		}, nil
	}
	roadmapItemList, err := roadmap_dao.RoadmapInfoDao.ListByOwner(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	//生成结果
	roadmapList := []*roadmap_api.RoadmapInfo{}
	for _, roadmapItem := range roadmapItemList {
		roadmap := roadmapItem.ToRoadmapInfo()
		roadmap.OwnerDisplayName = userItem.BasicInfo.DisplayName
		roadmap.OwnerLogoUri = userItem.BasicInfo.LogoUri
		roadmapList = append(roadmapList, roadmap)
	}

	return &roadmap_api.ListMyOwnResponse{
		Code:        roadmap_api.ListMyOwnResponse_CODE_OK,
		RoadmapList: roadmapList,
	}, nil
}

func (apiImpl *RoadmapApiImpl) ListById(ctx context.Context, req *roadmap_api.ListByIdRequest) (*roadmap_api.ListByIdResponse, error) {
	emptyList := []*roadmap_api.RoadmapInfo{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.ListByIdResponse{
			Code:        roadmap_api.ListByIdResponse_CODE_WRONG_SESSION,
			ErrMsg:      "会话不存在",
			RoadmapList: emptyList,
		}, nil
	}
	//列出我相关的roadmapId
	memberItemList, err := roadmap_dao.RoadmapMemberDao.ListByMember(ctx, sessItem.UserId)
	if err != nil {
		return nil, err
	}
	myRoadmapIdMap := map[string]bool{}
	for _, memberItem := range memberItemList {
		myRoadmapIdMap[memberItem.RoadmapId] = true
	}
	//列出roadmap
	tmpRoadmapItemList, err := roadmap_dao.RoadmapInfoDao.ListById(ctx, req.RoadmapIdList)
	if err != nil {
		return nil, err
	}
	roadmapItemList := []*roadmap_dao.RoadmapInfoDbItem{}
	for _, roadmapItem := range tmpRoadmapItemList {
		if roadmapItem.OwnerUserId == sessItem.UserId || myRoadmapIdMap[roadmapItem.RoadmapId] {
			roadmapItemList = append(roadmapItemList, roadmapItem)
		}
	}
	//补全用户信息
	userIdList := []string{}
	for _, roadmapItem := range roadmapItemList {
		userIdList = append(userIdList, roadmapItem.OwnerUserId)
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, userIdList)
	if err != nil {
		return nil, err
	}
	userItemMap := map[string]*user_dao.UserInfoDbItem{}
	for _, userItem := range userItemList {
		userItemMap[userItem.UserId] = userItem
	}

	//生成结果
	roadmapList := []*roadmap_api.RoadmapInfo{}
	for _, roadmapItem := range roadmapItemList {
		roadmap := roadmapItem.ToRoadmapInfo()
		userItem, ok := userItemMap[roadmapItem.OwnerUserId]
		if ok {
			roadmap.OwnerDisplayName = userItem.BasicInfo.DisplayName
			roadmap.OwnerLogoUri = userItem.BasicInfo.LogoUri
		}
		roadmapList = append(roadmapList, roadmap)
	}
	return &roadmap_api.ListByIdResponse{
		Code:        roadmap_api.ListByIdResponse_CODE_OK,
		RoadmapList: roadmapList,
	}, nil
}

func (apiImpl *RoadmapApiImpl) ListForApply(ctx context.Context, req *roadmap_api.ListForApplyRequest) (*roadmap_api.ListForApplyResponse, error) {
	roadmapItemList, err := roadmap_dao.RoadmapInfoDao.ListByApply(ctx, req.UserId)
	if err != nil {
		return nil, err
	}
	userItemList, err := user_dao.UserInfoDao.ListById(ctx, []string{req.UserId})
	if err != nil {
		return nil, err
	}
	//生成结果
	roadmapList := []*roadmap_api.RoadmapInfo{}
	for _, roadmapItem := range roadmapItemList {
		roadmap := roadmapItem.ToRoadmapInfo()

		if len(userItemList) > 0 {
			roadmap.OwnerDisplayName = userItemList[0].BasicInfo.DisplayName
			roadmap.OwnerLogoUri = userItemList[0].BasicInfo.LogoUri
		}
		roadmapList = append(roadmapList, roadmap)
	}

	return &roadmap_api.ListForApplyResponse{
		Code:        roadmap_api.ListForApplyResponse_CODE_OK,
		RoadmapList: roadmapList,
	}, nil
}

func (apiImpl *RoadmapApiImpl) Get(ctx context.Context, req *roadmap_api.GetRequest) (*roadmap_api.GetResponse, error) {
	emptyInfo := &roadmap_api.RoadmapInfo{
		BasicInfo: &roadmap_api.BasicRoadmapInfo{},
	}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_api.GetResponse{
			Code:    roadmap_api.GetResponse_CODE_WRONG_SESSION,
			ErrMsg:  "会话不存在",
			Roadmap: emptyInfo,
		}, nil
	}
	//获取roadmap
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_api.GetResponse{
			Code:    roadmap_api.GetResponse_CODE_NO_ROADMAP,
			ErrMsg:  "成长路线图不存在",
			Roadmap: emptyInfo,
		}, nil
	}
	if roadmapItem.OwnerUserId != sessItem.UserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return nil, err
		}
		if !exist {
			return &roadmap_api.GetResponse{
				Code:    roadmap_api.GetResponse_CODE_NO_PERMISSION,
				ErrMsg:  "没有权限",
				Roadmap: emptyInfo,
			}, nil
		}
	}
	//获取用户信息
	userItem, err := user_dao.UserInfoDao.GetById(ctx, roadmapItem.OwnerUserId)
	if err != nil {
		return nil, err
	}
	//生成结果
	roadmap := roadmapItem.ToRoadmapInfo()
	roadmap.OwnerDisplayName = userItem.BasicInfo.DisplayName
	roadmap.OwnerLogoUri = userItem.BasicInfo.LogoUri

	return &roadmap_api.GetResponse{
		Code:    roadmap_api.GetResponse_CODE_OK,
		Roadmap: roadmap,
	}, nil
}

func (apiImpl *RoadmapApiImpl) GetByInvite(ctx context.Context, req *roadmap_api.GetByInviteRequest) (*roadmap_api.GetByInviteResponse, error) {
	emptyInfo := &roadmap_api.RoadmapInfo{
		BasicInfo: &roadmap_api.BasicRoadmapInfo{},
	}

	inviteItem, err := roadmap_dao.InviteInfoDao.Get(ctx, req.InviteCode)
	if err != nil {
		return &roadmap_api.GetByInviteResponse{
			Code:    roadmap_api.GetByInviteResponse_CODE_NO_INVITE,
			ErrMsg:  "邀请不存在",
			Roadmap: emptyInfo,
		}, nil
	}
	//检查邀请是否过期
	nowTime := time.Now().UnixMilli()
	if inviteItem.ExpireTime < nowTime {
		return &roadmap_api.GetByInviteResponse{
			Code:    roadmap_api.GetByInviteResponse_CODE_NO_INVITE,
			ErrMsg:  "邀请不存在",
			Roadmap: emptyInfo,
		}, nil
	}

	//获取roadmap
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, inviteItem.RoadmapId)
	if err != nil {
		return &roadmap_api.GetByInviteResponse{
			Code:    roadmap_api.GetByInviteResponse_CODE_NO_ROADMAP,
			ErrMsg:  "成长路线图不存在",
			Roadmap: emptyInfo,
		}, nil
	}
	//获取用户信息
	userItem, err := user_dao.UserInfoDao.GetById(ctx, roadmapItem.OwnerUserId)
	if err != nil {
		return nil, err
	}
	//生成结果
	roadmap := roadmapItem.ToRoadmapInfo()
	roadmap.OwnerDisplayName = userItem.BasicInfo.DisplayName
	roadmap.OwnerLogoUri = userItem.BasicInfo.LogoUri

	return &roadmap_api.GetByInviteResponse{
		Code:    roadmap_api.GetByInviteResponse_CODE_OK,
		Roadmap: roadmap,
	}, nil
}
